package com.chengqj;

import com.chengqj.dao.UserDO;
import com.chengqj.repository.UserRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * Copyright © 2020年 com.qxkj. All rights reserved.
 *
 * @author chengqj
 * 异步线程调用事务不起作用
 * version 1.0.0 (接口必须带上)
 * @date 2020/11/5 16:43
 */
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private AsyncUserService asyncUserService;

    /**
     * 调用异步方法，异步中抛出异常主线程事务也不会回滚
     * 主线程和子线程的在事务上是相互隔离的，子线程的异常不会影响主线程的事务混滚与否（让若主线程不主动throw出异常，子线程即使抛出了异常也不会影响主线程的）
     * @param userDO
     * @return
     */
    @Transactional
    public UserDO callCommitAsync(UserDO userDO) {
        UserDO copyUserDo = new UserDO();
        BeanUtils.copyProperties(userDO, copyUserDo);
        userRepository.save(userDO);
        System.out.println( "当前：" + userDO.getId());
        //一定要放另一个service，直接放当前类成同步了
        asyncUserService.insert(copyUserDo);
        System.out.println("拷贝：" + copyUserDo.getId());
        return userDO;
    }
    /**
     * 调用异步方法
     * 主线程和异步线程都抛出异常时，都会进行回滚
     *
     * @param userDO
     * @return
     */
    @Transactional
    public UserDO callRollbackAsync(UserDO userDO) {
        UserDO copyUserDo = new UserDO();
        BeanUtils.copyProperties(userDO, copyUserDo);
        userRepository.save(userDO);
        //一定要放另一个service，直接放当前类成同步了
        asyncUserService.insert(copyUserDo);
        throw new RuntimeException();
    }

    /**
     * 获取用户数据
     *
     * @param id
     * @return
     */
    public UserDO getUserById(Long id) {
        Optional<UserDO> userOptional = userRepository.findById(id);
        if (userOptional.isPresent()) {
            return userOptional.get();
        }
        return null;
    }

}
